﻿#include "commonfunction.h"


bool deleteDir(const QString &path)
{
    if (path.isEmpty())
    {
          return false;
    }
    QDir dir(path);
    if(!dir.exists())
    {
        return true;
    }
    dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); //设置过滤
    QFileInfoList fileList = dir.entryInfoList(); // 获取所有的文件信息
    foreach (QFileInfo file, fileList)
    { //遍历文件信息
        if (file.isFile())
        { // 是文件，删除
            file.dir().remove(file.fileName());
        }else
        { // 递归调用函数，删除子文件夹
            deleteDir(file.absoluteFilePath());
        }
    }
    return dir.rmpath(dir.absolutePath()); // 这时候文件夹已经空了，再删除文件夹本身
}



bool comparsion_y(Point2f a, Point2f b){
    return a.y > b.y;
}

bool comparsion_x(Point2f a, Point2f b){
    return a.x > b.x;
}

//判断点是(x,y)否在椭圆内
//  圆心 centor_x centor_y x半长轴 a  y半长轴 b
bool isInsideEllipse(int centor_x, int centor_y, int x, int y, int a, int b) {
    int result = (pow((x - centor_x), 2) / pow(a, 2)) + (pow((y - centor_y), 2) / pow(b, 2));
    if(result<1)
        return true;
    else
        return false;
}

int gray_value_roi_mask(Mat image_src,Mat image_mask)
{
    if(image_src.empty())
    {
        return -1;
    }
    if(image_src.empty())
    {
        return -1;
    }
    if(image_src.channels()==3)
    {
        cvtColor(image_src,image_src,COLOR_BGR2GRAY);
    }
    if(image_mask.channels()==3)
    {
        cvtColor(image_mask,image_mask,COLOR_BGR2GRAY);
    }
//    imwrite("image_mask.png",image_mask);
//    imwrite("image_src.png",image_src);
    Scalar scalar = cv::mean(image_src,image_mask);
    int mean_value =0 ;
    mean_value = scalar.val[0] ;

    int mean_value_background =0 ;

    Mat image_mask_background = ~image_mask;
    Scalar scalar_background = cv::mean(image_src,image_mask_background);
    mean_value_background = scalar_background.val[0] ;

    return mean_value_background - mean_value;
}

int gray_value_roi(Mat image_src,int value_threshold,uint count_standard)
{
    if(value_threshold>=255)
    {
        return -1;
    }
    if(value_threshold<=0)
    {
        return -1;
    }
    if(image_src.empty())
    {
        return -1;
    }
    if(image_src.channels()==3)
    {
        cvtColor(image_src,image_src,COLOR_BGR2GRAY);
    }
    Mat image_threshold;
    threshold(image_src,image_threshold,value_threshold,255,THRESH_BINARY_INV);
    uint count_now = 0;

    int pixCnt = image_src.rows * image_src.cols;
    uchar* grayData= image_src.data;
        for (int pix=0; pix < pixCnt; pix++)//使用指针遍历
        {
            if(*grayData<value_threshold)
                 count_now = count_now+1;
            grayData++;//灰度图指针每次+1

        }

    if(count_now <count_standard )
    {
        return -1;
    }

    Scalar scalar = cv::mean(image_src,image_threshold);
    int mean_value =0 ;
    if(image_src.channels()==1)
    {

         mean_value = scalar.val[0] ;
    }
    return mean_value;
}



bool sort_x(Point2f a, Point2f b){
    return a.x > b.x;
}

int regionLocation(Mat image_src,int region_threshold_low,int region_threshold_up,cv::Point& point ,vector<Point>& vector_point_show)
{
    point.x=0;
    point.y=0;
    if(region_threshold_up>255)
    {
        return -1;
    }
    if(region_threshold_low<0)
    {
        return -1;
    }
    if(region_threshold_up -region_threshold_low <= 0)
    {
        return -1;
    }
    if(image_src.empty())
    {
        return -1;
    }
    if(image_src.channels()==3)
    {
        cvtColor(image_src,image_src,COLOR_BGR2GRAY);
    }
    Mat image_threshold;
    cv::threshold(image_src,image_threshold,region_threshold_low,region_threshold_up,THRESH_BINARY);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours( image_threshold, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE );

    if(contours.size() == 0)
    {
        return 0;
    }

    int max_size_index = 0;
    double max_size =0;
    for (int i=0;i<contours.size();i++)
    {
        double size_now = contourArea(contours[i]);
        if(size_now>max_size)
        {
            max_size = size_now;
            max_size_index = i;
        }
    }
    RotatedRect rotate_rect= minAreaRect(contours[max_size_index]);

//    point = rotate_rect.center;

    // 定义4个点的数组
    Point2f arr[4];
    rotate_rect.points(arr);
    // 将这四个点存储到arr数组中

    rotate_rect.points(arr);
    for (int i = 0; i < 4; i++)
    {
        vector_point_show.push_back(arr[i]);
    }


    vector<Point>  vector_point_sort;
    vector_point_sort.assign(vector_point_show.begin(),vector_point_show.end());
    sort(vector_point_sort.begin(), vector_point_sort.end(),sort_x);

    point = Point( (vector_point_sort[0].x + vector_point_sort[1].x)/2 , (vector_point_sort[0].y + vector_point_sort[1].y)/2 );

    return 0;
}

int measureHighlight(Mat image_src,int m_measure_threshold,double measure_height_max_threshold ,double m_measure_height_min_threshold,double measure_width_max_threshold ,double m_measure_width_min_threshold,vector<int>& vector_measure,vector<Point>& vector_point_show)
{
    if(m_measure_threshold>=255)
    {
        return -1;
    }
    if(image_src.empty())
    {
        return -1;
    }
    if(image_src.channels()==3)
    {
        cvtColor(image_src,image_src,COLOR_BGR2GRAY);
    }
    Mat image_threshold;
    threshold(image_src,image_threshold,m_measure_threshold,255,THRESH_BINARY);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours( image_threshold, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE );

    if(contours.size() == 0)
    {
        return 0;
    }

    int max_size_index = 0;
    double max_size =0;
    for (int i=0;i<contours.size();i++)
    {
        double size_now = contourArea(contours[i]);
        if(size_now>max_size)
        {
            max_size = size_now;
            max_size_index = i;
        }
    }
    RotatedRect rotate_rect= minAreaRect(contours[max_size_index]);
    // 定义4个点的数组
    Point2f arr[4];
    rotate_rect.points(arr);
    // 将这四个点存储到arr数组中

    rotate_rect.points(arr);
    for (int i = 0; i < 4; i++)
    {
        vector_point_show.push_back(arr[i]);
    }

//        Point2f pt1, pt2;
//        for (int i = 0; i < 4; i++)
//        {
//            // 1
//            pt1.x = arr[i].x;
//            pt1.y = arr[i].y;
//            pt2.x = arr[(i + 1) % 4].x;
//            pt2.y = arr[(i + 1) % 4].y;
//              line(image_show, pt1, pt2, Scalar(0, 255, 0), 2, 8);
//        }

    Rect rect = rotate_rect.boundingRect();

    int length1 = sqrt( pow((arr[0].x-arr[1].x),2) +  pow((arr[0].y-arr[1].y),2));
    int length2 = sqrt( pow((arr[2].x-arr[1].x),2) +  pow((arr[2].y-arr[1].y),2));



    int measurement_height = abs(length1 - rect.height) - abs(length2 - rect.height) < 0 ? length1:length2;
    int measurement_width = abs(length1 - rect.height) - abs(length2 - rect.height) > 0 ? length1:length2;

    vector_measure.push_back(measurement_height);
    vector_measure.push_back(measurement_width);

    if(measurement_height < measure_height_max_threshold && measurement_height>m_measure_height_min_threshold)
    {
        return 1;
    }

    if(measurement_width < measure_width_max_threshold && measurement_width>m_measure_width_min_threshold)
    {
        return 1;
    }

    return 0;
}

int detection_existance(Mat image,int detection_existance_threshold)
{
//    logger->info("start detection_existance:" + to_string(detection_existance_threshold));
    Scalar scalar = cv::mean(image);
     int mean_value =0 ;
    if(image.channels()==3)
    {

         mean_value = (scalar.val[0] + scalar.val[1] +scalar.val[2])/3;
    }
    if(image.channels()==1)
    {

         mean_value = scalar.val[0] ;
    }

    if(mean_value > detection_existance_threshold)
        return 1;
    else
        return 0;
}

QImage matToQImage(const Mat mat_in)
{
    cv::Mat mat = mat_in;
    if(mat.type() == CV_8UC1)
    {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        image.setColorCount(256);
        for(int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }
    else if(mat.type() == CV_8UC3)
    {
        QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        image = image.rgbSwapped();
        return image;
    }
    else if(mat.type() == CV_8UC4)
    {
        QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image;
    }
    else
    {
        return QImage();
    }
}

#include "sha.h"

#include <iostream>
#include <string>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
wstring Str2Wstr(string str)
{
    unsigned len = str.size() * 2;// 预留字节数
    setlocale(LC_CTYPE, "");     //必须调用此函数
    wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
    mbstowcs(p, str.c_str(), len);// 转换
    std::wstring str1(p);
    delete[] p;// 释放申请的内存
    return str1;
}
string exe_cmd(const char* cmd)
{
    wstring pszCmd_w = Str2Wstr(cmd);
    //wcout << "pszCmd_w is " << pszCmd_w << endl;
    // 创建匿名管道,write->read;
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    HANDLE hRead, hWrite;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0))
    {
        //cout << "@ CreatePipe failed!" << endl;
        return (" ");
    }
    //cout << "@0" << endl;
    // 设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite
    STARTUPINFO si = { sizeof(STARTUPINFO) }; // Pointer to STARTUPINFO structure;
    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    //si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE; //隐藏窗口；
    si.hStdError = hWrite;
    si.hStdError = hWrite;
    si.hStdOutput = hWrite; //管道的输入端口连接命令行的输出；
    // 启动命令行
    PROCESS_INFORMATION pi;// Pointer to PROCESS_INFORMATION structure;
    if (!CreateProcess(NULL,
        (LPWSTR)pszCmd_w.c_str(),
        NULL,
        NULL,
        TRUE,
        //FALSE,          // Set handle inheritance to FALSE
        NULL,
        //0,              // No creation flags
        NULL,
        NULL,
        &si,
        &pi))
    {
        //cout << "@ CreateProcess failed!" << endl;
        return ("Cannot create process");
    }
    CloseHandle(hWrite);//关闭管道的输入端口；
    // 读取命令行返回值
    string strRetTmp;
    char buff[1024] = { 0 };
    DWORD dwRead = 0;
    strRetTmp = buff;
    while (ReadFile(hRead, buff, 1024, &dwRead, NULL))//从管道的输出端获取命令行写入的数据；
    {
        //cout << "buff = " << buff << endl;
        strRetTmp += buff;
    }
    CloseHandle(hRead);//关闭管道的输出端口；
    //cout << "strRetTmp:" << strRetTmp << endl;

    int first = strRetTmp.find('\n') + 1;
    string subresult = strRetTmp.substr(first, strRetTmp.size() - first);

    int second = subresult.find(' ') + 1;
    string subresult2 = subresult.substr(0, second - 1);
    return subresult2;

}
#include <fstream>


bool isValidInteger(const std::string& str) {
    if (str.empty()) return false;

    size_t start = 0;
    // 检查是否有符号前缀（+/-）
    if (str[0] == '+' || str[0] == '-') {
        if (str.length() == 1) return false; // 仅有符号，没有数字
        start = 1;
    }

    // 检查剩余字符是否全为数字
    for (size_t i = start; i < str.length(); ++i) {
        if (!std::isdigit(str[i])) return false;
    }

    return true;
}

int64_t verify(const char* license_path)
{
    string  cpu = exe_cmd("wmic cpu get ProcessorID");
    string  disk = exe_cmd("wmic diskdrive where index=0 get serialnumber");

    string cpu_disk = cpu + disk;
    unsigned char sha512Code[64];

    SHA512_CB sha512;

    SHA512Init(&sha512);
    SHA512Update(&sha512, (unsigned char*)(cpu_disk.c_str()), strlen(cpu_disk.c_str()));
    SHA512Final(&sha512, sha512Code);


    unsigned char sha512CodeIn[64];
    ifstream in(license_path, ifstream::in | ios::binary);
    in.read(reinterpret_cast<char*>(sha512CodeIn), sizeof(sha512CodeIn));


    cout << endl;
    int ret = memcmp(sha512CodeIn, sha512Code, sizeof(sha512CodeIn));
    if (ret != 0)
    {
        in.close();
        return 0;
    }



    string string_values;
    in >> string_values;


    int64_t value=0;
    try {
        value = std::stoll(string_values); // 安全调用
    } catch (const std::invalid_argument& e) {
        return 0;
    } catch (const std::out_of_range& e) {
        return 0;
    }





    return value;
}
